package com.jianying.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.jianying.domain.Bargain;
import com.jianying.domain.Category;
import com.jianying.domain.Currency;
import com.jianying.domain.Customer;
import com.jianying.domain.Enumeration;
import com.jianying.domain.Notice;
import com.jianying.domain.Order;
import com.jianying.domain.Payment;
import com.jianying.domain.Product;
import com.jianying.domain.ProductShare;
import com.jianying.domain.Purchase;
import com.jianying.domain.Quotation;
import com.jianying.domain.Settlement;
import com.jianying.domain.SettlementItem;
import com.jianying.domain.Supplier;
import com.jianying.domain.Tenant;
import com.jianying.domain.TenantConnection;
import com.jianying.domain.User;
import com.jianying.mapper.BargainMapper;
import com.jianying.mapper.CategoryMapper;
import com.jianying.mapper.CurrencyMapper;
import com.jianying.mapper.CustomerMapper;
import com.jianying.mapper.EnumerationMapper;
import com.jianying.mapper.NoticeMapper;
import com.jianying.mapper.OrderMapper;
import com.jianying.mapper.PaymentMapper;
import com.jianying.mapper.ProductMapper;
import com.jianying.mapper.ProductShareMapper;
import com.jianying.mapper.PurchaseMapper;
import com.jianying.mapper.QuotationMapper;
import com.jianying.mapper.SettlementItemMapper;
import com.jianying.mapper.SettlementMapper;
import com.jianying.mapper.SupplierMapper;
import com.jianying.mapper.TenantConnectionMapper;
import com.jianying.mapper.TenantMapper;
import com.jianying.mapper.UserMapper;
import com.jianying.service.InfoSynchronousService;
import com.jianying.shared.Utils;

@Service("infoSynchronousService")
public class InfoSynchronousServiceImpl implements InfoSynchronousService {
	
	@Resource
	private TenantMapper tenantMapper;
	
	@Resource
	private UserMapper userMapper;
	
	@Resource
	private CategoryMapper categoryMapper;
	
	@Resource
	private EnumerationMapper enumerationMapper;
	
	@Resource
	private CurrencyMapper currencyMapper;
	
	@Resource
	private ProductMapper productMapper;
	
	@Resource
	private OrderMapper orderMapper;
	
	@Resource
	private PurchaseMapper purchaseMapper;
	
	@Resource
	private QuotationMapper quotationMapper;
	
	@Resource
	private ProductShareMapper productShareMapper;
	
	@Resource
	private TenantConnectionMapper tenantConnectionMapper;
	
	@Resource
	private CustomerMapper customerMapper;
	
	@Resource
	private SupplierMapper supplierMapper;
	
	@Resource
	private BargainMapper bargainMapper;
	
	@Resource
	private SettlementMapper settlementMapper;
	
	@Resource
	private SettlementItemMapper settlementItemMapper;
	
	@Resource
	private PaymentMapper paymentMapper;
	
	@Resource
	private NoticeMapper noticeMapper;

	@Override
	public void synchronousTenant() {
		List<Tenant> tenants = tenantMapper.all();
		for (Tenant tenant : tenants) {
			Integer id = tenant.getId();
			insertTenant(tenant);
			insertUser(tenant);
			insertCurrency(tenant);
			insertCategory(tenant, id);
			insertEnumerations(tenant, id);
		}
	}

	private void insertCategory(Tenant tenant, Integer id) {
		List<Category> categories = categoryMapper.all(id);
		if(categories != null && !categories.isEmpty()){
			categories.forEach(c->c.setTenantId(tenant.getId()));
			categoryMapper.insertBatch(categories);
		}
	}

	private void insertEnumerations(Tenant tenant, Integer id) {
		List<Enumeration> enumerations = enumerationMapper.all(id);
		if(enumerations !=null && !enumerations.isEmpty()){
			enumerations.forEach(e->e.setTenantId(tenant.getId()));
			enumerationMapper.insertBatch(enumerations);
		}
		
	}

	private void insertCurrency(Tenant tenant) {
		List<Currency> currencies = new ArrayList<>();
		Currency currency = new Currency();
		currency.setCnyRate(1.0);
		currency.setCode("CNY");
		currency.setSymbol("￥");
		currency.setTenantId(tenant.getId());
		currencies.add(currency);
		currencyMapper.insertBatch(currencies);
	}

	private void insertUser(Tenant tenant) {
		User user = new User();
		user.setAdmin(true);
		user.setCreatedAt(tenant.getCreatedAt());
		user.setIndustry(tenant.getIndustry());
		user.setName(tenant.getName());
		user.setOpenid(tenant.getOpenid());
		user.setPhone(tenant.getPhone());
		user.setTenantId(tenant.getId());
		user.setUnionid(tenant.getUnionid());
		userMapper.insert(user);
	}

	private void insertTenant(Tenant tenant) {
		tenant.setEdition("pro");
		tenant.setIdentifier(Utils.randomNumber(6));
		tenantMapper.insert(tenant);
	}

	@Override
	public void synchronousProduct() {
		List<Tenant> tenants = tenantMapper.all();
		for (Tenant tenant : tenants) {
			User user = userMapper.findByUnionid(tenant.getUnionid());
			if(user != null){
				insertProduct(tenant, user);
			}
		}
	}

	private void insertProduct(Tenant tenant, User user) {
		List<Product> products = productMapper.all(tenant.getId());
		for (Product product : products) {
			Category category = categoryMapper.find(product.getCategoryId());
			List<ProductShare> productShares = productShareMapper.byProductId(product.getId());
			if(category != null){
				Category c = categoryMapper.byName(user.getTenantId(), category.getName());
				if(c != null){
					product.setCategoryId(c.getId());
					product.setCategoryName(c.getName());
				}
			}
			product.setTenantId(user.getTenantId());
			productMapper.insert(product);
			if(productShares != null && !productShares.isEmpty()){
				List<Quotation> qs = new ArrayList<>();
				for (ProductShare productShare : productShares) {
					Integer id = productShare.getCustomerId();
					Quotation q = new Quotation();
					q.setHasInv(productShare.getHasInv());
					q.setHasInv(productShare.getHasInv());
					q.setQuoterId(user.getTenantId());
					q.setQuoterName(user.getTenant().getName());
					q.setPrice(productShare.getSharePrice());
					q.setProductId(product.getId());
					Tenant quoter = tenantMapper.findById(id);
					if(quoter != null){
						User inquirierUser = userMapper.findByUnionid(quoter.getUnionid());
						if(inquirierUser != null){
							q.setInquirierId(inquirierUser.getTenantId());
							q.setInquirierName(inquirierUser.getTenant().getName());
							Customer customer = customerMapper.byPhone(inquirierUser.getPhone(), user.getTenantId());
							if(customer != null){
								q.setCustomerId(customer.getId());
								q.setCustomerName(customer.getName());
								Supplier supplier = supplierMapper.find(customer.getSourceTenantId(), customer.getTenantId());
								System.out.println("-----------");
								if(supplier != null){
									q.setSupplierId(supplier.getId());
									q.setSupplierName(supplier.getName());
								}
							}
						}
					}
					qs.add(q);
				}
				quotationMapper.insertBatch(qs);
			}
		}
	}

	@Override
	public void synchronousCustomer() {
		insertCustomerAndSupplier();
	}

	private void insertCustomerAndSupplier() {
		List<TenantConnection> tenantConnections = tenantConnectionMapper.all();
		for (TenantConnection tenantConnection : tenantConnections) {
			Tenant customerTenant = tenantMapper.findById(tenantConnection.getSellerId());
			Tenant supplierTenant = tenantMapper.findById(tenantConnection.getSupplierId());
			if(customerTenant != null && supplierTenant != null && customerTenant.getUnionid() != null && supplierTenant.getUnionid() != null){
				User customer = userMapper.findByUnionid(customerTenant.getUnionid());
				User supplier = userMapper.findByUnionid(supplierTenant.getUnionid());
				customerMapper.insert(new Customer(tenantConnection.getSellerNickename(), customer.getPhone(), tenantConnection.getSellerAddress(), tenantConnection.getSellerCity()
						, tenantConnection.getSellerAddress(), supplier.getPhone(), supplier.getId(), customer.getTenantId(), supplier.getTenantId(), "retail", null));
			    supplierMapper.insert(new Supplier(tenantConnection.getSupplierNickname(), supplier.getPhone(), tenantConnection.getSellerProvince()
			    		, tenantConnection.getSupplierCity(), tenantConnection.getSupplierAddress(), customer.getPhone(), customer.getId(), supplier.getTenantId(), customer.getTenantId()));
			}
			
		}
	}

	@Override
	public void synchronousOrder() {
		List<Order> orders = orderMapper.all();
		if (orders != null && !orders.isEmpty()) {
			List<Order> unplaceOrders = orders.stream().filter(o -> o.getFollow().equals(false))
					.collect(Collectors.toList());
			if (unplaceOrders != null && !unplaceOrders.isEmpty()) {
				List<String> orderUuids = unplaceOrders.stream().map(o -> o.getUuid()).collect(Collectors.toList());
				List<Purchase> purchases = purchaseMapper.byUuids(orderUuids);
				for (Order order : unplaceOrders) {
					Bargain bargain = insertBargain(order);
					bargainMapper.insert(bargain);
					order = setOrder(order, bargain);
					orderMapper.insert(order);
					for (Purchase purchase : purchases) {
						if(order.getUuid().equals(purchase.getUuid())){
						insertPlacedOrderAndPurchase(order, purchase);
						}
					}
				}
			}
		}
	}

	private void insertPlacedOrderAndPurchase(Order order, Purchase purchase) {
        Order o = orderMapper.find(purchase.getForwardId());
		Bargain b = insertBargain(o);
		bargainMapper.insert(b);
		Order setOrder = setOrder(o, b);
		orderMapper.insert(setOrder);
		purchase.setUuid(setOrder.getUuid());
		purchase.setOrderId(order.getId());
		purchase.setTenantId(order.getTenantId());
		purchase.setSupplierId(o.getTenantId());
		purchaseMapper.insert(purchase);
		List<String> uuids = new ArrayList<>();
		uuids.add(o.getUuid());
		List<Purchase> purchases = purchaseMapper.byUuids(uuids);
		if (purchases != null && !purchases.isEmpty()) {
			for (Purchase p : purchases) {
				insertPlacedOrderAndPurchase(o, p);
			}
		}

	}

	private Order setOrder(Order order, Bargain bargain) {
		order.setCurrency("CNY");
		if(order.getPrice() != null){
			order.setCnyPrice(order.getPrice() * order.getQuantity());
		}else{
			order.setCnyPrice(0.0);
		}
		order.setAssist(false);
		order.setBargainId(bargain.getId());
		order.setTenantId(bargain.getTenantId());
		return order;
	}

	private Bargain insertBargain(Order order) {
		Bargain b = new Bargain();
		if(order.getCustomerId() != null){
			TenantConnection tenantConnection = tenantConnectionMapper.find(order.getCustomerId(), order.getTenantId());
			if(tenantConnection != null){
				Tenant customerTenant = tenantMapper.findById(tenantConnection.getSellerId());
				User customer = userMapper.findByUnionid(customerTenant.getUnionid());
				Tenant supplierTenant = tenantMapper.findById(order.getTenantId());
				if(supplierTenant != null && customer != null){
					User supplier = userMapper.findByUnionid(supplierTenant.getUnionid());
					Customer c = customerMapper.byPhone(customer.getPhone(), supplier.getTenantId());
					b.setCustomerId(c.getId());
				}
			}
		}
		b.setCustomerName(order.getCustomerName());
//				b.setAmount(amount);
		Tenant supplierTenant = tenantMapper.findById(order.getTenantId());
		if(supplierTenant != null){
			User supplier = userMapper.findByUnionid(supplierTenant.getUnionid());
			b.setTenantId(supplier.getTenantId());
			b.setOwnerId(supplier.getId());
		}
		b.setCurrency("CNY");
		b.setSerialNo(order.getSerialNo());
		b.setSettleType("later");
		b.setUuid(Utils.uuid());
		return b;
	}

	@Override
	public void synchronousSettlement() {
		List<Tenant> tenants = tenantMapper.all();
		for (Tenant tenant : tenants) {
			List<Settlement> settlements = settlementMapper.all(tenant.getId());
			for (Settlement settlement : settlements) {
				Integer id = settlement.getId();
				Tenant customerTenant = tenantMapper.findById(settlement.getSellerId());
				User customer = userMapper.findByUnionid(customerTenant.getUnionid());
				Tenant supplierTenant = tenantMapper.findById(settlement.getSupplierId());
				User supplier = userMapper.findByUnionid(supplierTenant.getUnionid());
				if(customer != null){
					settlement.setClientTenantId(customer.getTenantId());
					settlement.setClientId(customer.getId());
				}
				settlement.setClientName(settlement.getSellerName());
				settlement.setSettlerId(supplier.getId());
				settlement.setSettlerName(settlement.getSupplierName());
				settlement.setSettlerTenantId(supplier.getTenantId());
				settlementMapper.insert(settlement);
				List<SettlementItem> settlementItems = settlementItemMapper.bySettlementId(id);
				for (SettlementItem settlementItem : settlementItems) {
					Order order = orderMapper.find(settlementItem.getOrderId());
//					Order o = orderMapper.byUuid(order.getUuid());
					settlementItem.setRecordUuid(order.getUuid());
					settlementItem.setSettlementId(settlement.getId());
				}
				settlementItemMapper.insertBatch(settlementItems);
				List<Payment> payments = paymentMapper.findBySettlementId(id);
				if(payments != null){
					for (Payment payment : payments) {
						payment.setSettlementId(settlement.getId());
						paymentMapper.insert(payment);
					}
				}
			}
		}
	}

	@Override
	public void synchronousNotice() {
		List<Tenant> tenants = tenantMapper.all();
		for (Tenant tenant : tenants) {
			List<Notice> notices = noticeMapper.all(tenant.getId());
			for (Notice notice : notices) {
				Tenant senderTenant = tenantMapper.findById(notice.getSenderId());
				Tenant receiverTenant = tenantMapper.findById(notice.getReceiverId());
				if(senderTenant != null && receiverTenant != null){
					User sender = userMapper.findByUnionid(senderTenant.getUnionid());
					User receiver = userMapper.findByUnionid(receiverTenant.getUnionid());
					noticeMapper.insert(new Notice(notice.getContent(), sender.getId(), notice.getSenderName(), sender.getTenantId()
							, receiver.getId(), notice.getReceiverName(), receiver.getTenantId(), notice.getReadAt()));
				}
			}
		}
	}

}
